using Circus.CodeEditor;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
namespace Circus.Syntax.Lexer
{
	public class LexSyntaxBlock
	{
		private string name = string.Empty;
		private string desc = string.Empty;
		private LexStyle style;
		private LexState leaveState;
		private IList<string> expressions;
		private LexReswordSets reswordSets;
		private LexState state;
		private bool caseSensitive;
		[Description("Gets or sets a value indicating whether \"LexSyntaxBlock\" is case-sensitive or not.")]
		public virtual bool CaseSensitive
		{
			get
			{
				return this.caseSensitive;
			}
			set
			{
				if (this.caseSensitive != value)
				{
					this.caseSensitive = value;
					this.OnCaseSensitiveChanged();
				}
			}
		}
		public LexState State
		{
			get
			{
				return this.state;
			}
			set
			{
				if (this.state != value)
				{
					this.state = value;
					this.OnStateChanged();
				}
			}
		}
		[Description("Gets or sets name of the \"LexSyntaxBlock\".")]
		public virtual string Name
		{
			get
			{
				return this.name;
			}
			set
			{
				if (this.name != value)
				{
					this.name = value;
					this.OnNameChanged();
				}
			}
		}
		[Description("Gets or sets description of the \"LexSyntaxBlock\".")]
		public virtual string Desc
		{
			get
			{
				return this.desc;
			}
			set
			{
				if (this.desc != value)
				{
					this.desc = value;
					this.OnDescChanged();
				}
			}
		}
		[Description("Gets or sets an \"ILexStyle\" object, applicable for text that matches \"LexSyntaxBlock\" expression.")]
		public virtual LexStyle Style
		{
			get
			{
				return this.style;
			}
			set
			{
				if (this.style != value)
				{
					this.style = value;
					this.OnStyleChanged();
				}
			}
		}
		[Description("Gets or sets \"ILexState\" object that specifies lexical resulting state after lexical analyzer locates text, that matches to the \"LexSyntaxBlock.Expression\".")]
		public virtual LexState LeaveState
		{
			get
			{
				return this.leaveState;
			}
			set
			{
				if (this.leaveState != value)
				{
					this.leaveState = value;
					this.OnLeaveStateChanged();
				}
			}
		}
		[Description("Gets or sets collection of the \"ILexReswordSet\" object containing reserwed words.")]
		public virtual LexReswordSets ReswordSets
		{
			get
			{
				return this.reswordSets;
			}
			set
			{
				this.reswordSets.Clear();
				foreach (LexReswordSet current in value)
				{
					this.reswordSets.Add(current);
				}
				this.OnReswordSetsChanged();
			}
		}
		[Description("Represents a list of regular expression patterns for the \"LexSyntaxBlock.Expressions\".")]
		public IList<string> Expressions
		{
			get
			{
				return this.expressions;
			}
			set
			{
				this.expressions.Clear();
				foreach (string current in value)
				{
					this.expressions.Add(current);
				}
				this.OnExpressionsChanged();
			}
		}
		[Description("Represents a collective regular expression pattern for the \"LexSyntaxBlock.Expressions\".")]
		public virtual string Expression
		{
			get
			{
				string result;
				switch (this.expressions.Count)
				{
				case 0:
					result = string.Empty;
					break;
				case 1:
					result = this.expressions[0];
					break;
				default:
				{
					StringBuilder stringBuilder = new StringBuilder();
					foreach (string current in this.expressions)
					{
						stringBuilder.Append(string.Format("({0})", current) + "|");
					}
					if (stringBuilder.Length > 0)
					{
						stringBuilder.Remove(stringBuilder.Length - 1, 1);
					}
					result = stringBuilder.ToString();
					break;
				}
				}
				return result;
			}
		}
		[Description("Represents index of the \"LexSyntaxBlock\" within the lexical syntax block collection.")]
		public virtual int Index
		{
			get
			{
				return (this.state != null) ? this.state.SyntaxBlocks.IndexOf(this) : -1;
			}
		}
	
		protected virtual void OnStateChanged()
		{
		}
		protected virtual void OnNameChanged()
		{
		}
		protected virtual void OnDescChanged()
		{
		}
		protected virtual void OnStyleChanged()
		{
		}
		protected virtual void OnLeaveStateChanged()
		{
		}
		protected virtual void OnReswordSetsChanged()
		{
		}
		protected virtual void OnExpressionsChanged()
		{
		}
		protected virtual void OnCaseSensitiveChanged()
		{
			foreach (LexReswordSet current in this.reswordSets)
			{
				current.CaseSensitive = this.caseSensitive;
			}
		}
		public LexSyntaxBlock()
		{
			this.expressions = new List<string>();
			this.reswordSets = new LexReswordSets(this);
		}
		public LexSyntaxBlock(LexState state) : this()
		{
			this.state = state;
		}
		public virtual int FindResword(string resword)
		{
			int result;
			for (int i = 0; i < this.reswordSets.Count; i++)
			{
				if (this.reswordSets[i].FindResword(resword))
				{
					result = i;
					return result;
				}
			}
			result = -1;
			return result;
		}
		public virtual int AddExpression(string expression)
		{
			this.expressions.Add(expression);
			return this.expressions.Count - 1;
		}
	}
}
